/**
 * @file   USB2XXX_CANFD_Test.cpp
 * @brief  CANFD数据收发测试程序
 * @author wdluo(wdluo@toomoss.com)
 * @version 1.0
 * @date 2022-12-03
 * @copyright Copyright (c) 2022 重庆图莫斯电子科技有限公司
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "offline_type.h"
#include "usb_device.h"
#include "usb2canfd.h"
#if _WIN32
#include <windows.h>
#pragma comment(lib,"USB2XXX.lib")
#endif
/*
在运行程序前，请先将两个通道对接，也就是CAN1_H接CAN2_H，CAN1_L接CAN2_L
本程序实现CAN1发送数据，CAN2接收数据功能
若是向其他设备进行数据收发，注意波特率一定要匹配上
*/
int main(int argc, const char* argv[])
{
    DEVICE_INFO DevInfo;
    int DevHandle[10];
    int SendCANIndex = 0;//发送CAN通道号
    int ReceiveCANIndex = 0;//接收CAN通道号
    bool state;
    int ret;
    //扫描连接到电脑的设备，并获取设备号
    ret = USB_ScanDevice(DevHandle);
    if(ret <= 0){
        printf("No device connected!\n");
        return 0;
    }
    //打开设备
    state = USB_OpenDevice(DevHandle[0]);
    if(!state){
        printf("Open device error!\n");
        return 0;
    }
    char FunctionStr[256]={0};
    //获取设备固件信息
    state = DEV_GetDeviceInfo(DevHandle[0],&DevInfo,FunctionStr);
    if(!state){
        printf("Get device infomation error!\n");
        return 0;
    }else{
        printf("Firmware Info:\n");
	    printf("Firmware Name:%s\n",DevInfo.FirmwareName);
        printf("Firmware Build Date:%s\n",DevInfo.BuildDate);
        printf("Firmware Version:v%d.%d.%d\n",(DevInfo.FirmwareVersion>>24)&0xFF,(DevInfo.FirmwareVersion>>16)&0xFF,DevInfo.FirmwareVersion&0xFFFF);
        printf("Hardware Version:v%d.%d.%d\n",(DevInfo.HardwareVersion>>24)&0xFF,(DevInfo.HardwareVersion>>16)&0xFF,DevInfo.HardwareVersion&0xFFFF);
    }
    CANFD_INIT_CONFIG CANFDConfig;
    //获取波特率参数并初始化配置CAN
    ret = CANFD_GetCANSpeedArg(DevHandle[0],&CANFDConfig,500000,2000000);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Get Speed Error!\n");
        return 0;
    }else{
        printf("CANFD Get Speed Success!\n");
    }
    CANFDConfig.ISOCRCEnable = 1;//设置CANFD校验模式
    CANFDConfig.ResEnable = 1;   //是否使能适配器内部120欧终端电阻，若需要使能则设置为1，否则设置为0
    ret = CANFD_Init(DevHandle[0],SendCANIndex,&CANFDConfig);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Init Error!\n");
        return 0;
    }else{
        printf("CANFD Init Success!\n");
    }
    ret = CANFD_Init(DevHandle[0],ReceiveCANIndex,&CANFDConfig);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Init Error!\n");
        return 0;
    }else{
        printf("CANFD Init Success!\n");
    }
    //设置过滤器
    CANFD_FILTER_CONFIG CANFilter;
    CANFilter.Enable = 1;
    CANFilter.Index = 0;
    CANFilter.__Res0=0;
    CANFilter.__Res1=0;
    CANFilter.ID_Accept = 0x123;
    CANFilter.ID_Mask = 0x1FFFFFFF;
    //ret = CANFD_SetFilter(DevHandle[0],ReceiveCANIndex,&CANFilter,1);
    //启动接收数据
    ret = CANFD_StartGetMsg(DevHandle[0], ReceiveCANIndex);
    if (ret != CANFD_SUCCESS){
        printf("Start receive CANFD failed!\n");
        return 0;
    }else{
        printf("Start receive CANFD Success!\n");
    }
    //准备发送数据
    CANFD_MSG CanMsg[5];
    for (int i = 0; i < 5; i++){
        CanMsg[i].Flags = 0;//CANFD_MSG_FLAG_FDF;//bit[0]-BRS,bit[1]-ESI,bit[2]-FDF,bit[6..5]-Channel,bit[7]-RXD
        CanMsg[i].DLC = 8;
        CanMsg[i].ID = (i);//将帧设置为扩展帧
        for (int j = 0; j < CanMsg[i].DLC; j++){
            CanMsg[i].Data[j] = j;
        }
        CanMsg[i].TimeStamp = 0;
    }
    int SendedMsgNum = CANFD_SendMsg(DevHandle[0], SendCANIndex, CanMsg, 5);
    if (SendedMsgNum >= 0){
        printf("Success send frames:%d\n", SendedMsgNum);
    }else{
        printf("Send CAN data failed!\n");
        return 0;
    }
    //延时一段时间后开始读数据
#if _WIN32
    Sleep(50);
#else
    usleep(50*1000);
#endif
    //读取CAN数据
    CANFD_MSG CanMsgBuffer[1024];
    int GetMsgNum = CANFD_GetMsg(DevHandle[0], ReceiveCANIndex, CanMsgBuffer, 1024);
    if (GetMsgNum > 0){
        for (int i = 0; i < GetMsgNum; i++){
            uint64_t tus = ((((uint64_t)CanMsgBuffer[i].TimeStampHigh<<32)|CanMsgBuffer[i].TimeStamp)*10.0);
            printf("CanMsg[%d].ID = 0x%08X\n", i, CanMsgBuffer[i].ID & CANFD_MSG_FLAG_ID_MASK);
            printf("CanMsg[%d].TimeStamp = %.6f s\n", i, tus/1000000.0);
            printf("CanMsg[%d].Data = ", i);
            for (int j = 0; j < CanMsgBuffer[i].DLC; j++)
            {
                printf("0x%02X ", CanMsgBuffer[i].Data[j]);
            }
            printf("\n");
        }
    }else if (GetMsgNum < 0){
        printf("Get CAN data error!\n");
    }
    //ͣ停止接收数据
    ret = CANFD_StopGetMsg(DevHandle[0], SendCANIndex);
    if (ret != CANFD_SUCCESS){
        printf("Stop receive CANFD failed!\n");
        return 0;
    }else{
        printf("Stop receive CANFD Success!\n");
    }
    //关闭设备
    USB_CloseDevice(DevHandle[0]);
    getchar();
    return 0;
}

